package {{packageName}}.core.{{entity.module}}.service;

{{#if entity.hasBigDecimal}}
import java.math.BigDecimal;
{{/if}}
import java.util.*;

import org.springframework.data.domain.Page;
import com.alibaba.fastjson.JSONObject;
{{#entity.enableEntityCache}}
import org.springframework.cache.annotation.CacheEvict;
{{/entity.enableEntityCache}}
import cn.ibizlab.util.security.SpringContextHolder;
import cn.ibizlab.util.domain.ImportResult;
import cn.ibizlab.util.enums.CheckKeyStatus;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.domainClassName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
{{#entity.relEntities}}
import {{packageName}}.core.{{module}}.domain.{{domainClassName}};
{{/entity.relEntities}}

/**
 * {{entity.logicName}}服务接口[{{entity.codeName}}Service]
 *
 * @author generator
 */
public interface {{entity.codeName}}Service{

    /**
     * 获取当前Service
     *
     * @return
     */
    default {{entity.codeName}}Service getSelf() {
        return SpringContextHolder.getBean(this.getClass());
    }

    {{#each entity.methods}}
    {{#if dataSet}}
    /**
    * fetch{{pascalCase codeName}}
    * {{memo}}
    * @param {{inParamName}}
    * @return
    */
    {{outParam}} fetch{{pascalCase codeName}}({{inParam}} {{inParamName}});

    /**
    * list{{pascalCase codeName}}
    * {{memo}}
    * @param {{inParamName}}
    * @return
    */
    List<{{entity.domainClassName}}> list{{pascalCase codeName}}({{inParam}} {{inParamName}});

    {{else if builtinAction}}
        {{#if (eq codeName 'Get')}}
    /**
    * 获取
    * @param {{inParamName}}
    * @return
    */
    default {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}}) {
        return getSelf().{{camelCase codeName}}(new {{entity.domainClassName}}().set{{pascalCase entity.keyField.codeName}}({{inParamName}}));
    }

    /**
     * 获取
     * @param et
     * @return
     */
    {{outParam}} {{camelCase codeName}}({{entity.domainClassName}} et);

    /**
     * id集合获取
     * @param keys
     * @return
     */
    default List<{{outParam}}> {{camelCase codeName}}(Collection<{{inParam}}> keys) {
        List<{{entity.domainClassName}}> entities =new ArrayList<>();
        keys.forEach(key -> entities.add(new {{entity.domainClassName}}().set{{pascalCase entity.keyField.codeName}}(key)));
        return getSelf().get(entities);
    }

    /**
    * 对象集合获取
    * @param entities
    * @return
    */
    List<{{outParam}}> {{camelCase codeName}}(List<{{entity.domainClassName}}> entities);

        {{else if (eq codeName 'GetDraft')}}
    /**
    * 草稿
    * @param {{inParamName}}
    * @return
    */
    {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}});

        {{else if (eq codeName 'CheckKey')}}
    /**
    * checkKey
    * @param {{inParamName}}
    * @return
    */
    CheckKeyStatus {{camelCase codeName}}({{inParam}} {{inParamName}});

        {{else if (eq codeName 'Create')}}
    /**
    * 创建
    * @param {{inParamName}}
    * @return
    */
    {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}});

    /**
     * 批量创建
     * @param list
     * @return
     */
    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    {{outParam}} {{camelCase codeName}}(List<{{inParam}}> list);

        {{else if (eq codeName 'Update')}}
    /**
    * 更新
    * @param {{inParamName}}
    * @return
    */
    {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}});

    /**
     * 批量更新
     * @param list
     * @return
     */
    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    {{outParam}} {{camelCase codeName}}(List<{{inParam}}> list);

        {{else if (eq codeName 'Save')}}
    /**
    * 保存
    * @param {{inParamName}}
    * @return
    */
    {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}});

	/**
     * 批量保存
     * @param list
     * @return
     */
    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    {{outParam}} {{camelCase codeName}}(List<{{inParam}}> list);

        {{else if (eq codeName 'Remove')}}
    /**
     * 主键删除
     * @param key
     * @return
     */
    default {{outParam}} {{camelCase codeName}}({{entity.keyField.type.java}} key) {
        return getSelf().{{camelCase codeName}}(new {{entity.domainClassName}}().set{{pascalCase entity.keyField.codeName}}(key));
    }

    /**
     * 根据对象删除
     * @param et
     * @return
     */
    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", key = "'row:'+#p0.{{camelCase entity.keyField.codeName}}")
    {{/entity.enableEntityCache}}
    {{outParam}} {{camelCase codeName}}({{entity.domainClassName}} et);

    /**
     * 批量删除
     * @param keys
     * @return
     */
    default {{outParam}} {{camelCase codeName}}(Collection<{{entity.keyField.type.java}}> keys) {
        List<{{entity.domainClassName}}> entities =new ArrayList<>();
        keys.forEach(key -> entities.add(new {{entity.domainClassName}}().set{{pascalCase entity.keyField.codeName}}(key)));
        return getSelf().{{camelCase codeName}}(entities);
    }

    /**
     * 批量删除对象
     * @param entities
     * @return
     */
    {{outParam}} {{camelCase codeName}}(List<{{entity.domainClassName}}> entities);

        {{/if}}
    {{else if reference}}
        {{#if (eq type 'find')}}
    /**
    * {{camelCase codeName}}
    * @param {{camelCase fkField.codeName}}s
    * @return
    */
    default {{outParam}} {{camelCase codeName}}(List<{{inParam}}> {{inParamName}}s){
        return new ArrayList<>();
    }

    default {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}}){
        return findBy{{pascalCase relation.codeName}}(new {{entityDomainClassName}}().set{{pascalCase relEntity.keyField.codeName}}({{inParamName}}));
    }
	
        {{else if (eq type 'findByCode')}}
    /**
    * {{camelCase codeName}}
    * @param {{camelCase entityCodeName}}
    * @return
    */
    default {{outParam}} {{camelCase codeName}}({{inBody}}){
        return findBy{{pascalCase fkField.codeName}}(Arrays.asList({{camelCase entityCodeName}}.get{{pascalCase relField.codeName}}()));
    }

        {{else if (eq type 'remove')}}
    /**
    * {{camelCase codeName}}
    * @param {{camelCase fkField.codeName}}
    * @return
    */
    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    {{outParam}} {{camelCase codeName}}({{inBody}});

        {{else if (eq type 'reset')}}
    /**
    * {{camelCase codeName}}
    * @param {{camelCase fkField.codeName}}
    * @return
    */
    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    {{outParam}} {{camelCase codeName}}({{inBody}});

        {{else if (eq type 'save')}}
    /**
    * {{camelCase codeName}}
    * @param {{camelCase fkField.codeName}}
    * @param list
    * @return
    */
    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default {{outParam}} {{camelCase codeName}}({{inBody}}){
        return getSelf().saveBy{{pascalCase relation.codeName}}(new {{entityDomainClassName}}().set{{pascalCase relEntity.keyField.codeName}}({{camelCase fkField.codeName}}),list);
    }

        {{else if (eq type 'saveByCode')}}
    /**
    * {{camelCase codeName}}
    * @param {{camelCase entityCodeName}}
    * @param list
    * @return
    */
    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    {{outParam}} {{camelCase codeName}}({{inBody}});

        {{/if}}
    {{else if nested}}
    default {{outParam}} {{camelCase codeName}}({{inBody}}) {
        return new ArrayList<>();
    }

    {{else if nestedObj}}
    default {{outParam}} {{camelCase codeName}}({{inBody}}) {
        return et.{{camelCase codeName}}();
    }

    {{else}}
    /**
    * {{camelCase codeName}}
    * {{memo}}
    * @param {{inParamName}}
    * @return
    */
    default {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}}) {
        {{#if voidReturn}}
        return {{inParamName}};
        {{else if needInParamConvert}}
        return getSelf().{{camelCase codeName}}(new {{entity.domainClassName}}().set{{pascalCase entity.keyField.codeName}}({{inParamName}}));
        {{else}}
            {{#eq inParam outParam}}
        return {{inParamName}};
            {{else}}
                {{#eq outParam 'Boolean'}}
        return false;
                {{else}}
                {{#startsWith outParam 'List'}}
        return new ArrayList<>();
                {{else}}
        return null;
                {{/startsWith}}
                {{/eq}}
            {{/eq}}
        {{/if}}
    }

    {{/if}}
    {{/each}}

    default ImportResult importData(String config, Boolean ignoreError, List<{{entity.domainClassName}}> list) {
        ImportResult rt = new ImportResult().setTotal(list.size());
        for(int i=0;i<list.size();i++) {
            {{entity.domainClassName}} et=list.get(i);
            try {
                this.getSelf().save(et);
                rt.setSuccess(rt.getSuccess()+1);
            }catch (Exception ex){
                rt.addItem(i+1,et.get{{#if entity.majorField}}{{pascalCase entity.majorField.codeName}}{{else}}{{pascalCase entity.keyField.codeName}}{{/if}}(),ex.getMessage());
                if(!ignoreError)
                    break;
            }
        }
        return rt;
    }
	
    /**
     * 创建实体对象
     * @return
     */
    default {{entity.domainClassName}} getEntity() {
        return new {{entity.domainClassName}}();
    }

    /**
     * 创建搜索对象
     * @return
     */
    default {{entity.codeName}}SearchContext getSearchContext() {
        return new {{entity.codeName}}SearchContext();
    }

}